package com.game.src.main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.text.StyledEditorKit.BoldAction;

public class Game extends Canvas implements Runnable {

	private static final long serialVersionUID = 1L;
	public static final int WIDTH = 320;
	public static final int HEIGHT = WIDTH / 12 * 9;
	public static final int SCALE = 2;
	public final String TITLE = "2D Space Game";

	private boolean running = false;
	private Thread thread;
	private double y;

	private BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
			BufferedImage.TYPE_INT_RGB);
	private BufferedImage spriteSheet = null;
	private BufferedImage background = null;
	private BufferedImage spriteSheetExp = null;

	private boolean is_shooting = false;

	private Player p;
	private Controller c;
	private Textures tex;
	private boolean pause = false;

	public void init() {

		requestFocus();
		BufferedImageLoader loader = new BufferedImageLoader();

		try {
			spriteSheet = loader.loadImage("/spritesheet.png");
			background = loader.loadImage("/background.png");
			spriteSheetExp = loader.loadImage("/spritesheet.png");
		} catch (IOException e) {
			e.printStackTrace();
		}

		addKeyListener(new KeyInput(this));

		tex = new Textures(this);

		newGame();

	}
	
	public void newGame(){
		p = new Player(this, 290, 400, tex);
		c = new Controller(this, tex);
	}

	public synchronized void start() {
		if (running) {
			return;
		}

		running = true;
		thread = new Thread(this);
		thread.start();
	}

	public synchronized void stop() {
		if (!running) {
			return;
		}

		running = false;
		try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.exit(1);
	}

	public void run() {

		init();
		long lastTime = System.nanoTime();
		final double amountOfTicks = 60.0;
		double ns = 1000000000 / amountOfTicks;
		double delta = 0;
		int updates = 0;
		int frames = 0;
		long timer = System.currentTimeMillis();

		while (running) {
			// game loop
			long now = System.nanoTime();

			delta += (now - lastTime) / ns;
			lastTime = now;

			if (delta >= 1) {
				tick();
				updates++;
				delta= 0;
				render();
				frames++;
			}

			if (System.currentTimeMillis() - timer > 1000) {
				timer += 1000;
				System.out.println(updates + " Ticks, Fps " + frames +", Object: " + c.getSize());
				updates = 0;
				frames = 0;
			}
		}
		stop();
	}

	private void tick() {


		if (pause) {
			return;
		}

		y += 5;
		if (y == 480) {
			y = 0;
		}
		p.tick();
		c.tick();
		// b.tick();
	}

	private void render() {

		BufferStrategy bs = this.getBufferStrategy();
		if (bs == null) {
			createBufferStrategy(3);
			return;
		}
		Graphics g = bs.getDrawGraphics();
		// ////////////////////////////////

		g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
		g.drawImage(background, 0, (int) y, null);
		g.drawImage(background, 0, (int) y - 480, null);
		
		

		p.render(g);
		c.render(g);
		
		g.setColor(Color.GREEN);
		g.setFont(new Font("Impact", Font.BOLD, 40));
		
		g.drawString("Score: " + p.getScore(), 10, 40);
		g.drawString("HP:" + p.getHealth(), 500,40);//nur um zu gucken ob das leben geht
		if (pause) {
			g.setFont(new Font("Impact", Font.PLAIN, 100));
			g.drawString("Pause", 190, 260);
		}

		// ////////////////////////////////
		g.dispose();
		bs.show();
	}

	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();

		if (key == KeyEvent.VK_RIGHT) {
			p.setVelX(8);
		} else if (key == KeyEvent.VK_LEFT) {
			p.setVelX(-8);
		} else if (key == KeyEvent.VK_DOWN) {
			p.setVelY(8);
		} else if (key == KeyEvent.VK_UP) {
			p.setVelY(-8);
		} else if (key == KeyEvent.VK_SPACE && !is_shooting) {
			p.setShooting(true);
		} else if (key == KeyEvent.VK_P) {
			pause = !pause;
		} else if (key == KeyEvent.VK_ESCAPE){
			System.exit(0);
		} else if (key == KeyEvent.VK_N){
			this.newGame();
		}
	}

	public void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();

		if (key == KeyEvent.VK_RIGHT) {
			p.setVelX(0);
		} else if (key == KeyEvent.VK_LEFT) {
			p.setVelX(0);
		} else if (key == KeyEvent.VK_DOWN) {
			p.setVelY(0);
		} else if (key == KeyEvent.VK_UP) {
			p.setVelY(0);
		} else if (key == KeyEvent.VK_SPACE) {
			p.setShooting(false);
		}
	}

	public static void main(String[] args) {
		Game game = new Game();

		game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

		JFrame frame = new JFrame(game.TITLE);
		frame.add(game);
		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);

		game.start();
	}

	public BufferedImage getSpriteSheet() {
		return spriteSheet;
	}

	public BufferedImage getSpriteSheetExp() {
		return spriteSheetExp;
	}

	/**
	 * @return the p
	 */
	public Player getPlayer() {
		return p;
	}

	/**
	 * @return the c
	 */
	public Controller getController() {
		return c;
	}

}
